package team.seekers.hula.course.course.controller;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import team.seekers.hula.common.annotation.ApiResponseBody;
import team.seekers.hula.course.resource.sectionContent.entity.dto.SectionContentDTO;
import team.seekers.hula.course.resource.sectionContent.entity.dto.SectionContentUpdateDTO;
import team.seekers.hula.auth.service.MindUtils;
import team.seekers.hula.course.resource.exam.dao.ExamDao;
import team.seekers.hula.course.resource.exam.entity.dao.ExamDO;
import team.seekers.hula.course.resource.sectionContent.dao.SectionContentDao;
import team.seekers.hula.course.resource.sectionContent.entity.dao.SectionContentDO;
import team.seekers.hula.course.resource.sectionContent.entity.dto.SectionContentCreateDTO;
import team.seekers.hula.course.resource.sectionContent.service.SectionContentService;
import team.seekers.hula.course.structure.chapter.dao.ChapterDao;
import team.seekers.hula.course.structure.chapter.entity.dao.ChapterDO;
import team.seekers.hula.course.structure.chapter.entity.dto.ChapterCreateDTO;
import team.seekers.hula.course.structure.section.dao.SectionDao;
import team.seekers.hula.course.structure.section.entity.dao.SectionDO;
import team.seekers.hula.course.structure.section.entity.dto.SectionCreateDTO;

import java.util.ArrayList;
import java.util.List;


@Controller
@ApiResponseBody
@RequestMapping("/manage/course")
public class CourseStructureManageController {

    @Autowired
    private ChapterDao chapterDao;

    @Autowired
    private SectionDao sectionDao;

    @Autowired
    private SectionContentDao sectionContentDao;

    @Autowired
    private SectionContentService sectionContentService;

    @Autowired
    private ExamDao examDao;


    /***********************************课程生成后微操（毛细血管级操作）********************************/

    /********************新增*****************/
    @PostMapping("/addChapter")
    public void addChapter(@RequestBody ChapterCreateDTO chapterCreateDTO){
        // 获取sequence
        chapterCreateDTO.setSequence(
                chapterDao.lambdaQuery()
                        .eq(ChapterDO::getCourseId, chapterCreateDTO.getCourseId())
                        .count());

        // 那么需要在此处生成富文本课时
        chapterCreateDTO.getLinkSectionContent().setUserId(MindUtils.getUserId());
        chapterCreateDTO.getLinkSectionContent().setSequence(0);
        chapterCreateDTO.setLinkId(sectionContentService.save(chapterCreateDTO.getLinkSectionContent()));

        ChapterDO chapterDO = new ChapterDO();
        BeanUtils.copyProperties(chapterCreateDTO,chapterDO);
        chapterDao.save(chapterDO);

        sectionContentDao.lambdaUpdate()
                .set(SectionContentDO::getChapterId,chapterDO.getId())
                .eq(SectionContentDO::getId,chapterCreateDTO.getLinkId())
                .update();
    }

    @PostMapping("/addSection")
    public void addSection(@RequestBody SectionCreateDTO sectionCreateDTO){
        // 获取课程id
        sectionCreateDTO.setCourseId(
                chapterDao.lambdaQuery()
                        .select(ChapterDO::getCourseId)
                        .eq(ChapterDO::getId, sectionCreateDTO.getChapterId())
                        .one()
                        .getCourseId());

        // 获取sequence
        sectionCreateDTO.setSequence(
                sectionDao.lambdaQuery()
                        .eq(SectionDO::getChapterId, sectionCreateDTO.getChapterId())
                        .count());

        // 如果绑定的是富文本课时，那么需要在此处生成
        if(sectionCreateDTO.getType() == 0){
            sectionCreateDTO.getLinkSectionContent().setUserId(MindUtils.getUserId());
            sectionCreateDTO.getLinkSectionContent().setSequence(0);
            sectionCreateDTO.setLinkId(sectionContentService.save(sectionCreateDTO.getLinkSectionContent()));
        }

        // 生成节
        SectionDO sectionDO = new SectionDO();
        BeanUtils.copyProperties(sectionCreateDTO,sectionDO);
        sectionDao.save(sectionDO);

        // 回填测试和课时的节id
        if(sectionCreateDTO.getType() == 0){
            sectionContentDao.lambdaUpdate().set(SectionContentDO::getSectionId,sectionDO.getId()).eq(SectionContentDO::getId,sectionCreateDTO.getLinkId()).update();
        }else{
            examDao.lambdaUpdate().set(ExamDO::getSectionId,sectionDO.getId()).eq(ExamDO::getId,sectionCreateDTO.getLinkId()).update();
        }
    }

    @PostMapping("/addSectionContent")
    public void addSectionContent(@RequestBody SectionContentCreateDTO sectionContentCreateDTO){
        // 获取sequence
        sectionContentCreateDTO.setSequence(
                sectionContentDao
                        .lambdaQuery()
                        .eq(SectionContentDO::getSectionId, sectionContentCreateDTO.getSectionId())
                        .count()+1);
        // 获取用户id
        sectionContentCreateDTO.setUserId(MindUtils.getUserId());

        // 获取课程id
        sectionContentCreateDTO.setCourseId(
                sectionDao.lambdaQuery()
                        .select(SectionDO::getCourseId)
                        .eq(SectionDO::getId, sectionContentCreateDTO.getSectionId())
                        .one()
                        .getCourseId());

        // 获取章id
        sectionContentCreateDTO.setCourseId(
                sectionDao.lambdaQuery()
                        .select(SectionDO::getChapterId)
                        .eq(SectionDO::getId, sectionContentCreateDTO.getSectionId())
                        .one()
                        .getChapterId());



        sectionContentService.save(sectionContentCreateDTO);
    }

    /*******************修改****************/

    @PostMapping("/updateSectionContent")
    public SectionContentDTO updateSectionContent(@RequestBody SectionContentUpdateDTO updateDTO){
        return sectionContentService.update(updateDTO);
    }

    @GetMapping("/updateChapterName")
    public void updateChapterName(@RequestParam String chapterId,
                                  @RequestParam String chapterName){
        ChapterDO chapterDO = new ChapterDO();
        chapterDO.setName(chapterName);
        chapterDO.setId(chapterId);
        chapterDao.updateById(chapterDO);
    }

    @GetMapping("/updateSectionName")
    public void updateSectionName(@RequestParam String sectionId,
                                  @RequestParam String sectionName){
        SectionDO sectionDO = new SectionDO();
        sectionDO.setName(sectionName);
        sectionDO.setId(sectionId);
        sectionDao.updateById(sectionDO);
    }

    @GetMapping("/updateSectionContentName")
    public void updateSectionContentName(@RequestParam String sectionContentId,
                                         @RequestParam String sectionContentName){
        SectionContentDO sectionContentDO = new SectionContentDO();
        sectionContentDO.setName(sectionContentName);
        sectionContentDO.setId(sectionContentId);
        sectionContentDao.updateById(sectionContentDO);
    }

    /*******************顺序修改****************/

    @GetMapping("/upChapter")
    public void upChapter(@RequestParam String chapterId){
        ChapterDO chapterDO = chapterDao.getById(chapterId);
        Integer oldSequence  =chapterDO.getSequence();
        // 找到比自己顺序小的
        String upChapterId = chapterDao.lambdaQuery().select(
                ChapterDO::getId
        ).eq(ChapterDO::getCourseId, chapterDO.getCourseId()).eq(ChapterDO::getSequence, oldSequence - 1).one().getId();

        chapterDO = new ChapterDO();
        chapterDO.setSequence(oldSequence-1);
        chapterDO.setId(chapterId);
        chapterDao.updateById(chapterDO);

        chapterDO.setSequence(oldSequence);
        chapterDO.setId(upChapterId);
        chapterDao.updateById(chapterDO);
    }

    @GetMapping("/upSection")
    public void upSection(@RequestParam String sectionId){
        SectionDO sectionDO = sectionDao.getById(sectionId);
        Integer oldSequence  =sectionDO.getSequence();
        // 找到比自己顺序小的
        String upSectionId = sectionDao.lambdaQuery().select(
                SectionDO::getId
        ).eq(SectionDO::getChapterId, sectionDO.getChapterId()).eq(SectionDO::getSequence, oldSequence - 1).one().getId();

        sectionDO = new SectionDO();
        sectionDO.setSequence(oldSequence-1);
        sectionDO.setId(sectionId);
        sectionDao.updateById(sectionDO);
        sectionDO.setSequence(oldSequence);
        sectionDO.setId(upSectionId);
        sectionDao.updateById(sectionDO);
    }

    @GetMapping("/upSectionContent")
    public void upSectionContent(@RequestParam String sectionContentId){
        SectionContentDO sectionContentDO = sectionContentDao.getById(sectionContentId);
        Integer oldSequence  =sectionContentDO.getSequence();
        // 找到比自己顺序小的
        String upSectionContentId = sectionContentDao.lambdaQuery().select(
                SectionContentDO::getId
        ).eq(SectionContentDO::getSectionId, sectionContentDO.getSectionId()).eq(SectionContentDO::getSequence, oldSequence - 1).one().getId();

        sectionContentDO = new SectionContentDO();
        sectionContentDO.setSequence(oldSequence-1);
        sectionContentDO.setId(sectionContentId);
        sectionContentDao.updateById(sectionContentDO);
        sectionContentDO.setSequence(oldSequence);
        sectionContentDO.setId(upSectionContentId);
        sectionContentDao.updateById(sectionContentDO);
    }

    /********************删除******************/
    @GetMapping("/deleteChapter")
    public void deleteChapter(@RequestParam String chapterId){
        ChapterDO chapterDO = chapterDao.getById(chapterId);

        // 下面所有的章节sequence减一
        List<ChapterDO> list = chapterDao.lambdaQuery().select(
                ChapterDO::getId,
                ChapterDO::getSequence
        ).eq(ChapterDO::getCourseId, chapterDO.getCourseId()).gt(ChapterDO::getSequence, chapterDO.getSequence()).list();
        for (ChapterDO aDo : list) {
            aDo.setSequence(aDo.getSequence()-1);
        }
        chapterDao.updateBatchById(list);

        // 删除所有级联元素
        List<SectionDO> sectionDOS = sectionDao.lambdaQuery()
                .select(SectionDO::getId)
                .eq(SectionDO::getChapterId, chapterDO.getId())
                .list();

        ArrayList<String> sectionIds = new ArrayList<>();
        for (SectionDO sectionDO : sectionDOS) {
            sectionIds.add(sectionDO.getId());
        }

        if(sectionIds.size()>0){
            sectionContentDao.lambdaUpdate().in(SectionContentDO::getSectionId,sectionIds).remove();
            sectionDao.removeByIds(sectionIds);
        }

        // 删除自己
        chapterDao.removeById(chapterId);
    }

    @GetMapping("/deleteSection")
    public void deleteSection(@RequestParam String sectionId){
        SectionDO sectionDO = sectionDao.getById(sectionId);

        // 下面所有的章节sequence减一
        List<SectionDO> list = sectionDao.lambdaQuery().select(
                SectionDO::getId,
                SectionDO::getSequence
        ).eq(SectionDO::getChapterId, sectionDO.getChapterId())
                .gt(SectionDO::getSequence, sectionDO.getSequence()).list();
        for (SectionDO aDo : list) {
            aDo.setSequence(aDo.getSequence()-1);
        }
        sectionDao.updateBatchById(list);

        // 删除所有级联元素
        sectionContentDao.lambdaUpdate().eq(SectionContentDO::getSectionId,sectionId).remove();

        // TODO 删除绑定的课时或者测试

        // 删除自己
        sectionDao.removeById(sectionId);
    }

    @GetMapping("/deleteSectionContent")
    public void deleteSectionContent(@RequestParam String sectionContentId){
        SectionContentDO sectionContentDO = sectionContentDao.getById(sectionContentId);

        // 下面所有的章节sequence减一
        List<SectionContentDO> list = sectionContentDao.lambdaQuery().select(
                        SectionContentDO::getId,
                        SectionContentDO::getSequence
                ).eq(SectionContentDO::getSectionId, sectionContentDO.getSectionId())
                .gt(SectionContentDO::getSequence, sectionContentDO.getSequence()).list();
        for (SectionContentDO aDo : list) {
            aDo.setSequence(aDo.getSequence()-1);
        }
        sectionContentDao.updateBatchById(list);

        sectionContentDao.removeById(sectionContentId);
    }

}
